package com.whately.core.base.config;

import com.whately.core.base.exception.ServiceError;
import com.whately.core.base.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;

/**
 * 服务启动时，注册服务
 */
@Component
public class FrameServiceCaller {
	private final static Logger logger = LoggerFactory.getLogger(FrameServiceCaller.class);

	@Autowired
	private SpringConfigurer springConfigurer;

	/**
	 * 内部服务调用代理
	 *
	 * @param serviceMethod 传mapping里面method=后面的部分
	 * @param param 方法参数
	 * @return 返回值
	 */
	/*public <T> T call(String serviceMethod, Class<T> responseType, Object... param) {
		logger.info("call ufo service : {}", serviceMethod);
		ServiceMethod sm = springConfigurer.getServiceMap().get(serviceMethod);
		if (sm == null) {
			logger.error("not found service method name {} ",serviceMethod);
			throw new ServiceException(ServiceError.SERVICE_NOT_FOUND);
		}

		try {
			return (T) sm.call(param);
		} catch (Exception e) {
			logger.error("service 2 error : " + serviceMethod, e);
			if(e instanceof java.lang.reflect.InvocationTargetException ){
				Throwable targetException = ((InvocationTargetException) e).getTargetException();
				if(targetException instanceof ServiceException){
					throw (ServiceException)targetException;
				}
			}

			throw new RuntimeException(e);
		}
	}*/

	@SuppressWarnings("unchecked")
	public <T> T call(String serviceMethod, Object... param) {
		logger.info("call  service : {}", serviceMethod);
		ServiceMethod sm = springConfigurer.getServiceMap().get(serviceMethod);
		if (sm == null) {
			logger.error("not found service method name {} ",serviceMethod);
			throw new ServiceException(ServiceError.SERVICE_NOT_FOUND);
		}

		try {
			return (T) sm.call(param);
		} catch (Exception e) {
			logger.error("************************** service call error **************************");
			logger.error("************************** service error {} ,param {}" , serviceMethod,param);
			logger.error("************************** service call error **************************");
			if(e instanceof InvocationTargetException ){
				Throwable targetException = ((InvocationTargetException) e).getTargetException();
				if(targetException instanceof ServiceException){
					throw (ServiceException)targetException;
				}
			}

			throw new RuntimeException(e);

		}
	}


}
